<template>
  <view class="snake-game-container">
    <!-- 头部信息 -->
    <view class="game-header">
      <view class="header-title">贪吃蛇</view>
      <view class="user-info">{{ userName }}</view>
      <view class="score-info">分数: {{ gameState.scores?.[userId] || 0 }}</view>
      <view class="game-tip">{{ gameTip }}</view>
    </view>

    <!-- 游戏区域 -->
    <view class="game-area">
      <h2 class="game-title"><i class="fa fa-apple"></i> 贪吃蛇对战</h2>

      <!-- 玩家列表 -->
      <view class="player-list">
        <view class="player-card" :class="{ 'ready': players[0]?.ready }">{{ players[0]?.user_name || '等待加入...' }}
          <view class="status">{{ players[0]?.ready ? '已准备' : '未准备' }}</view>
        </view>
        <view class="player-card" :class="{ 'ready': players[1]?.ready }">{{ players[1]?.user_name || '等待加入...' }}
          <view class="status">{{ players[1]?.ready ? '已准备' : '未准备' }}</view>
        </view>
      </view>

      <!-- 游戏画布 -->
      <canvas canvas-id="snakeCanvas" class="game-canvas"></canvas>

      <!-- 控制按钮 -->
      <view class="control-buttons">
        <button @tap="startGame" v-if="!isGameStarted" class="start-btn">开始游戏</button>
        <button @tap="restartGame" v-if="isGameOver" class="restart-btn">重新开始</button>
        <button @tap="toggleReadyStatus" class="ready-btn">{{ isReady ? '取消准备' : '准备' }}</button>
        <button @tap="backToLobby" class="back-btn">返回大厅</button>
      </view>

      <!-- 虚拟摇杆 -->
      <view class="virtual-joystick" v-if="isMobile">
        <view class="joystick-base">
          <view 
            class="joystick-thumb" 
            @touchstart="handleJoystickStart"
            @touchmove="handleJoystickMove"
            @touchend="handleJoystickEnd"
          ></view>
        </view>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted, reactive, computed } from 'vue';
import { onPageShow, onPageHide } from '@dcloudio/uni-app';
import { 
  getUserInfo, 
  getRoomId, 
  initGameState, 
  updateGameTip, 
  isValidDirectionChange,
  GameStatus,
  Direction,
  initGamePlayers,
  updatePlayerInfo,
  removePlayer
} from '@/utils/game-utils';

import { createGameConnection, GameType } from '@/utils/websocket-manager';

import { createMessage, MessageType } from '@/utils/websocket-manager';

import { checkDeviceType, GestureController } from '@/utils/game-utils';
import { getCurrentUserInfo } from '@/utils/auth';

// 获取用户信息
const userInfo = getCurrentUserInfo();
const userId = userInfo?.userId || 'user123';
const userName = userInfo?.userName || '玩家1';

// 游戏状态
const gameState = reactive({
  ...initGameState(),
  snakes: {},
  foods: [],
  scores: {}, // 确保scores属性被初始化
  gridSize: 16,
  cellSize: 20
});

// 响应式变量
const roomId = ref(getRoomId());
const players = ref(initGamePlayers(userId, userName, 2)); // 确保players数组正确初始化
const isReady = ref(false);
const isGameStarted = ref(false);
const isGameOver = ref(false);
const gameTip = ref('等待玩家加入...');
const { isMobile } = checkDeviceType();
const touchStart = ref({ x: 0, y: 0 });
let gameInterval = null;
let wsManager = null;

/**
 * 初始化WebSocket连接
 */
function initWebSocket() {
  const roomId = uni.getStorageSync('roomId')
  console.log('贪吃蛇游戏初始化WebSocket，房间ID:', roomId)
  
  // 检查必要参数
  if (!roomId) {
    console.error('房间ID为空，无法初始化WebSocket')
    uni.showToast({
      title: '房间ID为空',
      icon: 'none',
      duration: 2000
    })
    return
  }
  
  if (!userId || !userName) {
    console.error('用户信息为空，无法初始化WebSocket')
    uni.showToast({
      title: '用户信息为空',
      icon: 'none',
      duration: 2000
    })
    return
  }
  
  try {
    // 使用全局WebSocket管理器，防止重复连接
    wsManager = createGameConnection(GameType.SNAKE, roomId, {
      onOpen: () => {
        console.log('贪吃蛇WebSocket连接成功')
        wsManager.resetPreventReconnect()
        uni.showToast({
          title: '连接成功',
          icon: 'success',
          duration: 1000
        })
        
        // 连接成功后立即发送加入消息
        const joinMessage = {
          type: 1, // JOIN
          user_id: userId,
          user_name: userName,
          room_id: String(roomId),
          content: `${userName} 加入了游戏房间`,
          time: Math.floor(Date.now() / 1000)
        }
        wsManager.send(joinMessage)
      },
      onJoin: (message) => {
        console.log('用户加入:', message)
        updatePlayerList(message)
      },
      onLeave: (message) => {
        console.log('用户离开:', message)
        updatePlayerList(message)
      },
      onReady: updatePlayerReadyStatus,
      onGameOp: handleGameOperation,
      onGameState: updateGameState,
      onGameStart: handleGameStart,
      onGameEnd: handleGameEnd,
      onUserListUpdate: handleUserListUpdate,
      onRoomUserCount: handleRoomUserCount,
      onError: (error) => {
        console.error('贪吃蛇WebSocket连接错误:', error)
        uni.showToast({
          title: '连接失败',
          icon: 'none',
          duration: 2000
        })
      }
    })
    
    console.log('WebSocket管理器创建完成，开始连接')
    wsManager.connect()
  } catch (error) {
    console.error('创建WebSocket管理器失败:', error)
    uni.showToast({
      title: '初始化失败',
      icon: 'none',
      duration: 2000
    })
  }
}

/**
 * 更新玩家列表
 */
function updatePlayerList(message) {
  console.log('更新玩家列表:', message)
  
  // 如果是加入消息，添加到玩家列表
  if (message.type === 1 || message.type === 'join') {
    const newPlayer = {
      user_id: message.user_id,
      user_name: message.user_name,
      ready: false
    }
    
    // 检查是否已存在
    const existingIndex = players.value.findIndex(p => p.user_id === newPlayer.user_id)
    if (existingIndex === -1) {
      players.value.push(newPlayer)
      console.log('添加新玩家:', newPlayer)
    } else {
      players.value[existingIndex] = newPlayer
      console.log('更新玩家信息:', newPlayer)
    }
  }
  // 如果是离开消息，从玩家列表中移除
  else if (message.type === 2 || message.type === 'leave') {
    const playerIndex = players.value.findIndex(p => p.user_id === message.user_id)
    if (playerIndex !== -1) {
      const removedPlayer = players.value.splice(playerIndex, 1)[0]
      console.log('移除玩家:', removedPlayer)
    }
  }
  
  // 强制触发响应式更新
  players.value = [...players.value]
  
  console.log('更新后的玩家列表:', players.value)
  
  // 更新游戏提示
  if (players.value.length === 1) {
    gameTip.value = '等待其他玩家加入...'
  } else if (players.value.length >= 2) {
    gameTip.value = '玩家已就位，准备开始游戏！'
  } else {
    gameTip.value = '等待玩家加入...'
  }
}

/**
 * 更新玩家准备状态
 */
function updatePlayerReadyStatus(message) {
  console.log('更新玩家准备状态:', message)
  
  // 更新指定玩家的准备状态
  if (message.user_id) {
    const playerIndex = players.value.findIndex(p => p.user_id === message.user_id);
    if (playerIndex !== -1) {
      players.value[playerIndex].ready = message.ready || false;
    }
  }
}

/**
 * 处理用户列表更新
 */
function handleUserListUpdate(message) {
  console.log('收到用户列表更新:', message)
  
  try {
    let userList = [];
    
    // 处理不同的消息格式
    if (message.content) {
      if (typeof message.content === 'string') {
        userList = JSON.parse(message.content);
      } else if (Array.isArray(message.content)) {
        userList = message.content;
      }
    } else if (message.data && Array.isArray(message.data)) {
      userList = message.data;
    }
    
    console.log('解析后的用户列表:', userList);
    
    // 更新玩家列表
    players.value = userList.map(user => ({
      user_id: user.user_id || user.userId,
      user_name: user.user_name || user.userName,
      ready: user.ready || false
    }));
    
    // 强制触发响应式更新
    players.value = [...players.value];
    
    console.log('更新后的玩家列表:', players.value);
    
    // 更新游戏提示
    if (players.value.length === 1) {
      gameTip.value = '等待其他玩家加入...';
    } else if (players.value.length >= 2) {
      gameTip.value = '玩家已就位，准备开始游戏！';
    } else {
      gameTip.value = '等待玩家加入...';
    }
    
    // 显示用户列表更新提示
    uni.showToast({
      title: `房间用户更新: ${players.value.length}人`,
      icon: 'none',
      duration: 1500
    });
  } catch (error) {
    console.error('解析用户列表失败:', error);
    console.error('原始消息:', message);
  }
}

/**
 * 处理房间人数更新
 */
function handleRoomUserCount(message) {
  console.log('收到房间人数更新:', message)
  
  if (message.data) {
    const { user_count, max_users } = message.data;
    console.log(`房间人数: ${user_count}/${max_users}`);
    
    // 更新游戏提示
    if (user_count === 1) {
      gameTip.value = '等待其他玩家加入...';
    } else if (user_count >= 2) {
      gameTip.value = '玩家已就位，准备开始游戏！';
    }
    
    // 强制触发响应式更新
    gameTip.value = gameTip.value;
  }
}

/**
 * 更新游戏状态
 */
function updateGameState(message) {
  // 实现游戏状态更新逻辑
  console.log('更新游戏状态:', message)
  
  // 更新游戏状态
  if (message.data) {
    gameState.status = message.data.status || gameState.status
    gameState.snakes = message.data.snakes || gameState.snakes
    gameState.foods = message.data.foods || gameState.foods
    gameState.scores = message.data.scores || gameState.scores
    
    // 重新渲染游戏
    renderGame()
  }
}

/**
 * 处理游戏开始
 */
function handleGameStart(message) {
  console.log('游戏开始:', message)
  
  // 更新游戏状态
  gameState.status = 'playing'
  isGameStarted.value = true
  isGameOver.value = false
  gameTip.value = '游戏开始！'
  
  // 启动游戏循环
  if (gameInterval) clearInterval(gameInterval)
  gameInterval = setInterval(updateGame, 200)
}

/**
 * 处理游戏结束
 */
function handleGameEnd(message) {
  console.log('游戏结束:', message)
  
  // 更新游戏状态
  gameState.status = 'gameover'
  gameTip.value = '游戏结束！'
  clearInterval(gameInterval)
  gameInterval = null
  isGameOver.value = true
  isGameStarted.value = false
  
  // 显示游戏结果
  if (message.data && message.data.winner) {
    uni.showToast({ title: `游戏结束，${message.data.winner}获胜！`, icon: 'none', duration: 2000 })
  }
}

/**
 * 处理游戏操作
 */
function handleGameOperation(message) {
  console.log('处理游戏操作:', message)
  
  // 更新指定玩家的蛇方向
  if (message.user_id && message.direction && gameState.snakes[message.user_id]) {
    const snake = gameState.snakes[message.user_id];
    
    // 防止180度转向
    if (
      (message.direction === 'UP' && snake.direction === 'DOWN') ||
      (message.direction === 'DOWN' && snake.direction === 'UP') ||
      (message.direction === 'LEFT' && snake.direction === 'RIGHT') ||
      (message.direction === 'RIGHT' && snake.direction === 'LEFT')
    ) {
      return;
    }
    
    snake.direction = message.direction;
  }
}

/**
 * 发送WebSocket消息
 */
function sendWebSocketMessage(message) {
  if (wsManager && wsManager.getConnected()) {
    wsManager.send(message)
  } else {
    console.warn('WebSocket未连接，无法发送消息')
  }
}

/**
 * 初始化游戏
 */
function initGame() {
  // 重置游戏状态
  gameState.status = 'waiting';
  gameState.snakes = {};
  gameState.foods = [];
  gameState.scores = {};

  // 添加当前玩家的蛇
  gameState.snakes[userId] = {
    segments: [
      { x: 8, y: 8 },
      { x: 7, y: 8 },
      { x: 6, y: 8 }
    ],
    direction: 'RIGHT',
    alive: true
  };

  // 初始化分数
  gameState.scores[userId] = 0;

  // 生成食物
  gameState.foods = [generateFood(), generateFood()];

  // 渲染游戏
  renderGame();
}

/**
 * 生成食物
 */
function generateFood() {
  // 随机生成食物位置
  const x = Math.floor(Math.random() * gameState.gridSize);
  const y = Math.floor(Math.random() * gameState.gridSize);

  // 检查是否与蛇重叠
  for (const uid in gameState.snakes) {
    const snake = gameState.snakes[uid];
    for (const segment of snake.segments) {
      if (segment.x === x && segment.y === y) {
        // 如果重叠，重新生成
        return generateFood();
      }
    }
  }

  return { x, y };
}

/**
 * 渲染游戏
 */
function renderGame() {
  const ctx = uni.createCanvasContext('snakeCanvas');
  const canvasWidth = gameState.gridSize * gameState.cellSize;
  const canvasHeight = gameState.gridSize * gameState.cellSize;

  // 清除画布
  ctx.clearRect(0, 0, canvasWidth, canvasHeight);

  // 绘制网格背景
  ctx.setFillStyle('#f1f5f9');
  ctx.fillRect(0, 0, canvasWidth, canvasHeight);

  ctx.setStrokeStyle('#e2e8f0');
  for (let i = 0; i <= gameState.gridSize; i++) {
    // 垂直线
    ctx.beginPath();
    ctx.moveTo(i * gameState.cellSize, 0);
    ctx.lineTo(i * gameState.cellSize, canvasHeight);
    ctx.stroke();

    // 水平线
    ctx.beginPath();
    ctx.moveTo(0, i * gameState.cellSize);
    ctx.lineTo(canvasWidth, i * gameState.cellSize);
    ctx.stroke();
  }

  // 渲染食物
  gameState.foods.forEach(food => {
    ctx.setFillStyle('#f59e42');
    ctx.beginPath();
    ctx.arc(
      food.x * gameState.cellSize + gameState.cellSize / 2,
      food.y * gameState.cellSize + gameState.cellSize / 2,
      gameState.cellSize / 2 - 2,
      0, 2 * Math.PI
    );
    ctx.fill();
  });

  // 渲染所有蛇
  Object.entries(gameState.snakes).forEach(([uid, snake]) => {
    const isCurrentPlayer = uid === userId;
    const headColor = isCurrentPlayer ? '#6366f1' : '#22c55e';
    const bodyColor = isCurrentPlayer ? '#a5b4fc' : '#bbf7d0';

    for (let j = 0; j < snake.segments.length; j++) {
      const segment = snake.segments[j];
      const isHead = j === 0;

      ctx.setFillStyle(isHead ? headColor : bodyColor);
      ctx.fillRect(
        segment.x * gameState.cellSize + 1,
        segment.y * gameState.cellSize + 1,
        gameState.cellSize - 2,
        gameState.cellSize - 2
      );

      // 为蛇头添加眼睛
      if (isHead) {
        ctx.setFillStyle('#ffffff');

        // 根据方向绘制眼睛
        const eyeSize = gameState.cellSize / 5;
        const eyeOffset = gameState.cellSize / 4;

        let leftEyeX, leftEyeY, rightEyeX, rightEyeY;

        switch (snake.direction) {
          case 'RIGHT':
            leftEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset * 2;
            leftEyeY = segment.y * gameState.cellSize + eyeOffset;
            rightEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset * 2;
            rightEyeY = segment.y * gameState.cellSize + gameState.cellSize - eyeOffset;
            break;
          case 'LEFT':
            leftEyeX = segment.x * gameState.cellSize + eyeOffset * 2;
            leftEyeY = segment.y * gameState.cellSize + eyeOffset;
            rightEyeX = segment.x * gameState.cellSize + eyeOffset * 2;
            rightEyeY = segment.y * gameState.cellSize + gameState.cellSize - eyeOffset;
            break;
          case 'UP':
            leftEyeX = segment.x * gameState.cellSize + eyeOffset;
            leftEyeY = segment.y * gameState.cellSize + eyeOffset * 2;
            rightEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset;
            rightEyeY = segment.y * gameState.cellSize + eyeOffset * 2;
            break;
          case 'DOWN':
            leftEyeX = segment.x * gameState.cellSize + eyeOffset;
            leftEyeY = segment.y * gameState.cellSize + gameState.cellSize - eyeOffset * 2;
            rightEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset;
            rightEyeY = segment.y * gameState.cellSize + gameState.cellSize - eyeOffset * 2;
            break;
          default:
            leftEyeX = segment.x * gameState.cellSize + eyeOffset;
            leftEyeY = segment.y * gameState.cellSize + eyeOffset;
            rightEyeX = segment.x * gameState.cellSize + gameState.cellSize - eyeOffset;
            rightEyeY = segment.y * gameState.cellSize + eyeOffset;
        }

        // 绘制左眼
        ctx.beginPath();
        ctx.arc(leftEyeX, leftEyeY, eyeSize, 0, 2 * Math.PI);
        ctx.fill();

        // 绘制右眼
        ctx.beginPath();
        ctx.arc(rightEyeX, rightEyeY, eyeSize, 0, 2 * Math.PI);
        ctx.fill();
      }
    }
  });

  ctx.draw();
}

/**
 * 开始游戏
 */
function startGame() {
  if (gameState.status === 'playing') return;

  gameState.status = 'playing';
  isGameStarted.value = true;
  isGameOver.value = false;
  gameTip.value = '游戏开始！';

  // 启动游戏循环
  if (gameInterval) clearInterval(gameInterval);
  gameInterval = setInterval(updateGame, 200);
}

/**
 * 更新游戏状态
 */
function updateGame() {
  // 移动所有蛇
  Object.entries(gameState.snakes).forEach(([uid, snake]) => {
    if (!snake.alive) return;

    const head = { ...snake.segments[0] };

    // 根据方向移动头部
    switch (snake.direction) {
      case 'UP':
        head.y--;
        break;
      case 'DOWN':
        head.y++;
        break;
      case 'LEFT':
        head.x--;
        break;
      case 'RIGHT':
        head.x++;
        break;
    }

    // 检查是否撞墙
    if (head.x < 0 || head.x >= gameState.gridSize || head.y < 0 || head.y >= gameState.gridSize) {
      snake.alive = false;
      return;
    }

    // 检查是否撞到自己或其他蛇
    let collision = false;
    Object.values(gameState.snakes).forEach(otherSnake => {
      for (let i = 0; i < otherSnake.segments.length; i++) {
        // 允许头部接触自己的尾部
        if (otherSnake === snake && i === otherSnake.segments.length - 1) continue;

        if (otherSnake.segments[i].x === head.x && otherSnake.segments[i].y === head.y) {
          collision = true;
          break;
        }
      }
    });

    if (collision) {
      snake.alive = false;
      return;
    }

    // 检查是否吃到食物
    let ate = false;
    for (let i = 0; i < gameState.foods.length; i++) {
      const food = gameState.foods[i];
      if (food.x === head.x && food.y === head.y) {
        // 吃到食物，增加分数
        gameState.scores[uid] = (gameState.scores[uid] || 0) + 1;
        // 生成新食物
        gameState.foods[i] = generateFood();
        // 蛇身增长
        snake.segments.unshift(head);
        ate = true;
        break;
      }
    }

    if (!ate) {
      // 没吃到食物，移动蛇
      snake.segments.unshift(head);
      snake.segments.pop();
    }
  });

  // 检查游戏是否结束
  let aliveCount = 0;
  for (const uid in gameState.snakes) {
    if (gameState.snakes[uid].alive) aliveCount++;
  }

  if (aliveCount <= 0 || (Object.keys(gameState.snakes).length > 1 && aliveCount <= 1)) {
    gameState.status = 'gameover';
    gameTip.value = '游戏结束！';
    clearInterval(gameInterval);
    gameInterval = null;
    isGameOver.value = true;
    isGameStarted.value = false;
  }

  // 更新UI
  renderGame();
}

/**
 * 重新开始游戏
 */
function restartGame() {
  initGame();
  startGame();
}

/**
 * 切换准备状态
 */
function toggleReadyStatus() {
  isReady.value = !isReady.value;
  gameTip.value = isReady.value ? '已准备' : '未准备';
  
  // 通过WebSocket发送准备状态消息
      const readyMessage = createMessage(MessageType.READY, { ready: isReady.value }, {
    userId,
    userName,
    roomId: roomId.value
  })
  
  sendWebSocketMessage(readyMessage);
}

/**
 * 改变蛇的方向
 */
function changeDirection(dir) {
  const snake = gameState.snakes[userId];
  if (!snake || !snake.alive) return;

  // 防止180度转向
  if (!isValidDirectionChange(snake.direction, dir)) {
    return;
  }

  snake.direction = dir;
  
  // 通过WebSocket发送游戏操作消息
      const message = createMessage(MessageType.GAME_OP, { direction: dir }, {
    userId,
    userName,
    roomId: roomId.value
  });
  sendWebSocketMessage(message);
}

/**
 * 处理触摸开始事件
 */
function handleTouchStart(e) {
  touchStart.value = {
    x: e.touches[0].clientX,
    y: e.touches[0].clientY
  };
}

/**
 * 处理触摸移动事件
 */
// 虚拟摇杆状态
const joystickState = reactive({
  active: false,
  baseX: 0,
  baseY: 0,
  thumbX: 0,
  thumbY: 0,
  maxDistance: 50
});

function handleJoystickStart(e) {
  const touch = e.touches[0];
  const rect = e.currentTarget.getBoundingClientRect();
  
  joystickState.active = true;
  joystickState.baseX = rect.left + rect.width / 2;
  joystickState.baseY = rect.top + rect.height / 2;
  joystickState.thumbX = touch.clientX;
  joystickState.thumbY = touch.clientY;
}

function handleJoystickMove(e) {
  if (!joystickState.active) return;
  e.preventDefault();
  
  const touch = e.touches[0];
  const dx = touch.clientX - joystickState.baseX;
  const dy = touch.clientY - joystickState.baseY;
  const distance = Math.sqrt(dx * dx + dy * dy);
  
  // 计算角度
  const angle = Math.atan2(dy, dx) * 180 / Math.PI;
  
  // 根据角度确定方向
  if (distance > 20) { // 最小移动阈值
    if (angle >= -45 && angle < 45) {
      changeDirection('RIGHT');
    } else if (angle >= 45 && angle < 135) {
      changeDirection('DOWN');
    } else if (angle >= 135 || angle < -135) {
      changeDirection('LEFT');
    } else {
      changeDirection('UP');
    }
  }
  
  // 限制摇杆移动范围
  const ratio = Math.min(1, joystickState.maxDistance / distance);
  joystickState.thumbX = joystickState.baseX + dx * ratio;
  joystickState.thumbY = joystickState.baseY + dy * ratio;
}

function handleJoystickEnd() {
  joystickState.active = false;
  // 摇杆复位
  joystickState.thumbX = joystickState.baseX;
  joystickState.thumbY = joystickState.baseY;
}

/**
 * 返回游戏大厅
 */
function backToLobby() {
  console.log('=== backToLobby 被调用 ===')
  
  // 清理游戏资源
  if (gameInterval) {
    clearInterval(gameInterval);
    gameInterval = null;
  }
  
  // 发送离开房间消息
  if (wsManager && wsManager.getConnected()) {
    console.log('backToLobby: 发送离开房间消息')
    try {
      const leaveMessage = {
        type: 2, // LEAVE
        user_id: userId,
        user_name: userName,
        room_id: roomId.value,
        content: `${userName} 离开了游戏房间`,
        time: Math.floor(Date.now() / 1000)
      }
      wsManager.send(leaveMessage)
      
      // 等待消息发送完成后再关闭连接
      setTimeout(() => {
        closeWebSocketConnection()
      }, 200) // 增加延迟确保消息发送
    } catch (error) {
      console.error('发送离开消息失败:', error)
      closeWebSocketConnection()
    }
  } else {
    closeWebSocketConnection()
  }
}

function closeWebSocketConnection() {
  // 强制关闭WebSocket连接
  if (wsManager) {
    console.log('backToLobby: 强制关闭WebSocket连接')
    try {
      wsManager.close();
    } catch (error) {
      console.error('关闭WebSocket连接时出错:', error)
    }
    wsManager = null;
  }

  // 清除房间ID和游戏状态
  uni.removeStorageSync('roomId')
  
  // 重置游戏状态
  isGameStarted.value = false
  isGameOver.value = false
  gameTip.value = '等待玩家加入...'
  players.value = []
  
  // 重置游戏状态
  gameState.status = 'waiting'
  gameState.snakes = {}
  gameState.foods = []
  gameState.scores = {}

  // 导航回游戏空间
  console.log('backToLobby: 导航回游戏空间')
  uni.navigateBack();
}

// 移除这个函数，因为已经在工具函数中定义了

// 生命周期钩子
onMounted(() => {
  console.log('贪吃蛇游戏页面挂载')
  
  // 初始化游戏
  initGame();

  // 立即初始化WebSocket连接
  console.log('立即初始化WebSocket')
  if (wsManager === null) {
    initWebSocket();
  } else {
    console.log('WebSocket管理器已存在')
  }

  // 监听键盘事件 (仅在非移动设备上)
  if (!isMobile) {
    // 使用标准的键盘事件监听
    const handleKeyDown = (e) => {
      switch (e.keyCode) {
        case 38: // 上
          changeDirection(Direction.UP);
          break;
        case 40: // 下
          changeDirection(Direction.DOWN);
          break;
        case 37: // 左
          changeDirection(Direction.LEFT);
          break;
        case 39: // 右
          changeDirection(Direction.RIGHT);
          break;
        case 13: // 回车
          if (!isGameStarted.value) startGame();
          else if (isGameOver.value) restartGame();
          break;
      }
    };
    
    // 添加键盘事件监听
    document.addEventListener('keydown', handleKeyDown);
    
    // 保存事件处理函数引用以便后续移除
    window.snakeKeyDownHandler = handleKeyDown;
  } else {
    // 移动设备手势控制初始化
    const query = uni.createSelectorQuery().in(this);
    query.select('.game-canvas').node().exec(res => {
      const canvasNode = res[0].node;
      if (canvasNode) {
        GestureController.init(canvasNode, (direction) => {
          const currentSnake = gameState.snakes[userId];
          if (currentSnake?.alive && isValidDirectionChange(currentSnake.direction, direction)) {
            currentSnake.direction = direction;
            const moveMessage = createMessage(MessageType.GAME_OP, { direction }, { userId, userName, roomId: roomId.value });
            sendWebSocketMessage(moveMessage);
          }
        });
      }
    });
  }
});

onUnmounted(() => {
  console.log('贪吃蛇游戏页面卸载')
  
  // 清理游戏资源
  if (gameInterval) {
    clearInterval(gameInterval);
    gameInterval = null;
  }
  
  // 安全关闭WebSocket连接
  if (wsManager) {
    console.log('页面卸载，关闭WebSocket连接')
    wsManager.close();
    wsManager = null;
  }

  // 移除键盘事件监听
  if (!isMobile && window.snakeKeyDownHandler) {
    document.removeEventListener('keydown', window.snakeKeyDownHandler);
    delete window.snakeKeyDownHandler;
  } else {
    // 清理移动设备手势控制
    const query = uni.createSelectorQuery().in(this);
    query.select('.game-canvas').node().exec(res => {
      const canvasNode = res[0].node;
      if (canvasNode) {
        canvasNode.removeEventListener('touchstart', GestureController.handleTouchStart);
        canvasNode.removeEventListener('touchend', GestureController.handleTouchEnd);
      }
    });
  }
});

// 页面显示时
onPageShow(() => {
  console.log('贪吃蛇游戏页面显示')
  
  // 检查是否还有房间ID，如果没有说明用户已经离开房间
  const currentRoomId = uni.getStorageSync('roomId')
  if (!currentRoomId) {
    console.log('房间ID已清除，用户已离开房间，不重新连接WebSocket')
    return
  }
  
  // 页面显示时，如果WebSocket未连接且管理器存在，尝试重新连接
  if (wsManager && !wsManager.getConnected() && !wsManager.getConnecting()) {
    console.log('页面显示，重新连接WebSocket')
    wsManager.connect()
  }
});

// 页面隐藏时
onPageHide(() => {
  console.log('贪吃蛇游戏页面隐藏')
  // 页面隐藏时，不关闭WebSocket连接，保持连接以便快速恢复
});
</script>

<style scoped src="./snake.css"></style>